package com.exam.base.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;

import com.exam.base.util.DaoHelperUtil;

public class AbstractDaoImpl<T> extends SqlSessionDaoSupport implements IAbstractDao<T> {
	
	@Autowired
	private SqlSessionTemplate sqlSessionTemplate; 
	protected String namespace = getDefaultSqlNamespace();
 
	public String getNamespace()
	{
		return namespace;
	}

	public void setNamespace(String namespace)
	{
		this.namespace = namespace.concat(".");
	}

	protected String getDefaultSqlNamespace()
	{
		Class<T> clazz = DaoHelperUtil.getClassGenricType(this.getClass(),0);
		String nameSpace = clazz.getSimpleName();
		return "nameSpace_" + nameSpace.concat(".");
	}

	public T findById(Object primaryKey)
	{
		// return (T)
		// sqlSessionTemplate.queryForObject(namespace.concat("selectByPrimaryKey"),
		// primaryKey);
		return (T) sqlSessionTemplate.selectOne(namespace.concat("selectByPrimaryKey"), primaryKey);
	}

	public Object add(T pojo)
	{
		return sqlSessionTemplate.insert(namespace.concat("insert"), pojo);
	}

	public boolean delete(Object id)
	{
		return sqlSessionTemplate.delete(namespace.concat("deleteByPrimaryKey"), id) == 1;
	}

	public boolean deleteByModel(Object criteria)
	{
		return sqlSessionTemplate.delete(namespace.concat("deleteByExample"), criteria) >= 1;
	}

	public boolean update(T pojo)
	{
		return sqlSessionTemplate.update(namespace.concat("updateByPrimaryKeySelective"), pojo) == 1;
	}

	public List<T> findByModel(Object criteria)
	{ 
		return (List<T>) sqlSessionTemplate.selectList(namespace.concat("selectByExample"), criteria);
	}
	
	public int countByModel(Object criteria)
	{
		return (Integer) sqlSessionTemplate.selectOne(namespace.concat("countByExample"), criteria);
	}

	public List<T> findByModelPage(Object criteria)
	{
		return sqlSessionTemplate.selectList(namespace.concat("selectByPage"), criteria);
	}

	public void batchCreate(final List<T> pojoList, final String sqlId) throws DataAccessException
	{

		SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
		try
		{
			int batch = 0;
			for (T record : pojoList)
			{
				session.insert(namespace.concat(sqlId), record);
				batch++;
				if (batch == 1000)
				{
					session.commit();
					session.clearCache();
					batch = 0;
				}
			}
			session.commit();
		}
		finally
		{
			session.close();
		}
	}

	public void batchUpdate(final List<T> pojoList, final String sqlId)
	{
		SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
		try
		{
			int batch = 0;
			for (T record : pojoList)
			{
				session.update(namespace.concat(sqlId), record);
				batch++;
				if (batch == 1000)
				{
					session.commit();
					session.clearCache();
					batch = 0;
				}
			}
			session.commit();
		}
		finally
		{
			session.close();
		}
	}

	public void batchDel(final List<Long> pojoList, final String sqlId)
	{
		SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
		try
		{
			int batch = 0;
			for (Long record : pojoList)
			{
				session.delete(namespace.concat(sqlId), record);
				batch++;
				if (batch == 1000)
				{
					session.commit();
					session.clearCache();
					batch = 0;
				}
			}
			session.commit();
		}
		finally
		{
			session.close();
		}
	}

	public boolean deleteByIds(List<String> ids)
	{
		// TODO Auto-generated method stub
		boolean allflag = true;

		if (ids == null || ids.size() == 0)
		{
			return allflag;
		}
		// 按800长度拆分
		Map<String, List<String>> idsMap = DaoHelperUtil.splitList(ids, 800);

		for (String key : idsMap.keySet())
		{
			List<String> keySplitIds = idsMap.get(key);
			boolean flag = sqlSessionTemplate.delete(namespace.concat("deleteByPrimaryKeys"), keySplitIds) == 1;
			if (flag == false)
			{
				allflag = false;
			}
		}

		return allflag;

	}

	public List<T> findByIds(List<String> ids)
	{
		List<T> allList = new ArrayList<T>();
		if (ids == null || ids.size() == 0)
		{
			return allList;
		}

		// 去重
		List<String> idsUnqiue = DaoHelperUtil.removeDuplicate(ids);
		// 按800长度拆分
		Map<String, List<String>> idsMap = DaoHelperUtil.splitList(idsUnqiue, 800);

		for (String key : idsMap.keySet())
		{
			List<String> keySplitIds = idsMap.get(key);
			List<T> splitList = (List<T>) sqlSessionTemplate.selectList(namespace.concat("selectByPrimaryKeys"), keySplitIds);
			allList.addAll(splitList);
		}
		return allList;
	}
	/**
	 * 按条件查询数据
	 * @param query
	 * @return
	 */
	public List<T> findByQuery(String query)
	{
		return sqlSessionTemplate.selectList(namespace.concat("selectByQueryContent"), query);
	}
	/**
	 * 按条件查询数据数量
	 * @param query
	 * @return
	 */
	public int countByQuery(String query)
	{
		return (Integer) sqlSessionTemplate.selectOne(namespace.concat("countByQueryContent"), query);
	}
 
}
